package grandehealth.AudioVideoSDK.WebRTC;

import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.util.Log;


import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.DataChannel;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnection.IceConnectionState;
import org.webrtc.SessionDescription;
import org.webrtc.VideoRenderer;

import java.util.LinkedList;

import grandehealth.AudioVideoSDK.WebRTCPeer.NBMMediaConfiguration;
import grandehealth.AudioVideoSDK.WebRTCPeer.NBMPeerConnection;
import grandehealth.AudioVideoSDK.WebRTCPeer.NBMWebRTCPeer;


public class MyWebRTCApp implements NBMWebRTCPeer.Observer {
    private final static String TAG = WebRtcClient.class.getCanonicalName();

    VideoRenderer.Callbacks localRender;
    VideoRenderer.Callbacks remoteRender;

    EglBase.Context renderEGLContext;

    public String isCallOtherUser = "isNoCall";

    public NBMWebRTCPeer    nbmWebRTCPeer;
    Context                 mContext;
    WebRtcClient            client;

    private int             getWidth;
    private int             getHeight;

    private String userId;
    private String fromUserId;
    private String connectionId;


    public MyWebRTCApp(WebRtcClient client, Context context, VideoRenderer.Callbacks localRender, int width, int height)
    {
        mContext = context;
        this.localRender = localRender;
        this.client = client;
        this.getWidth = width;
        this.getHeight = height;

//        Point displaySize = new Point();
//        NBMMediaConfiguration.NBMVideoFormat receiverVideoFormat = new NBMMediaConfiguration.NBMVideoFormat(width, height, ImageFormat.NV21, 30);
//        NBMMediaConfiguration mediaConfiguration = new NBMMediaConfiguration(receiverVideoFormat);
    }

    public MyWebRTCApp(WebRtcClient client, Context context, int width, int height,
                       EglBase.Context renderEGLContext, VideoRenderer.Callbacks localRender, VideoRenderer.Callbacks remoteRender )
    {
        mContext = context;
        this.renderEGLContext = renderEGLContext;
        this.localRender = localRender;
        this.remoteRender = remoteRender;
        this.client = client;

        this.getWidth = width;
        this.getHeight = height;
    }


    public void onNBMWebRTCPeer(){
        NBMMediaConfiguration.NBMVideoFormat receiverVideoFormat = new NBMMediaConfiguration.NBMVideoFormat( getWidth, getHeight, ImageFormat.JPEG, 30 );

        NBMMediaConfiguration mediaConfiguration = new NBMMediaConfiguration(
                NBMMediaConfiguration.NBMRendererType.OPENGLES,
                NBMMediaConfiguration.NBMAudioCodec.OPUS,
                0,
                NBMMediaConfiguration.NBMVideoCodec.VP8,
                0,
                receiverVideoFormat,
                NBMMediaConfiguration.NBMCameraPosition.FRONT );

        nbmWebRTCPeer = new NBMWebRTCPeer( mediaConfiguration, mContext, this , renderEGLContext, localRender, remoteRender );

        nbmWebRTCPeer.addIceServer("stun:77.72.174.163:3478");

        nbmWebRTCPeer.addIceServer("stun:stun1.l.google.com:19302");
        nbmWebRTCPeer.addIceServer("stun:stun2.l.google.com:19302");
        nbmWebRTCPeer.addIceServer("stun:stun3.l.google.com:19302");
        nbmWebRTCPeer.addIceServer("stun:stun4.l.google.com:19302");

        nbmWebRTCPeer.addIceServer("stun:stun.ekiga.net");
        nbmWebRTCPeer.addIceServer("stun:stun.ideasip.com");
        nbmWebRTCPeer.addIceServer("stun:stun.schlund.de");
        nbmWebRTCPeer.addIceServer("stun:stun.stunprotocol.org:3478");
        nbmWebRTCPeer.addIceServer("stun:stun.voiparound.com");


        nbmWebRTCPeer.addIceServer("stun:stun.voipbuster.com");
        nbmWebRTCPeer.addIceServer("stun:stun.voipstunt.com");
        nbmWebRTCPeer.addIceServer("stun:stun.voxgratia.org");
        nbmWebRTCPeer.addIceServer("stun:stun.services.mozilla.com");

        LinkedList<PeerConnection.IceServer> getIceServers =  nbmWebRTCPeer.getIceServers();
        getIceServers.add( new PeerConnection.IceServer( "turn:u1@106.14.207.179:3478", "u1","0" ) );
        getIceServers.add( new PeerConnection.IceServer( "turn:u1@101.251.225.38:3478", "u1","0" ) );
        nbmWebRTCPeer.setIceServers( getIceServers );

        nbmWebRTCPeer.initialize();
    }


    @Override
    public void onInitialize() {

    }

    /* Observer methods and the rest of declarations */
    public void onLocalSdpOfferGenerated(SessionDescription localSdpOffer, NBMPeerConnection connection) {
        Log.d(TAG, "onLocalSdpOfferGenerated");

        if ( this.isCallOtherUser.equals("isCallOtherUser") ){
            client.sendCallMessage(localSdpOffer);
            this.isCallOtherUser = "isNoCall";

        }else{
            client.sendMessage(new AcceptCallCommand(fromUserId, localSdpOffer.description));
        }
    }
    public void onLocalSdpAnswerGenerated(SessionDescription localSdpAnswer, NBMPeerConnection connection) {
        client.sendMessage(new AcceptCallCommand(fromUserId, localSdpAnswer.description));
        Log.d(TAG, "onLocalSdpAnswerGenerated");
    }
    public void onIceCandidate(IceCandidate localIceCandidate, NBMPeerConnection connection) {
        try {
            Log.d("TAG", "onIceCandidate");
            JSONObject payload = new JSONObject();
            payload.put("sdpMLineIndex", localIceCandidate.sdpMLineIndex);
            payload.put("sdpMid", localIceCandidate.sdpMid);
            payload.put("candidate", localIceCandidate.sdp);

            JSONObject response = new JSONObject();
            response.put("id", "onIceCandidate");
            response.put("candidate",payload);

            client.sendJsonMessage(response.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    public void onIceStatusChanged(IceConnectionState state, NBMPeerConnection connection) {
        Log.d(TAG, "onIceStatusChanged");
    }
    public void onRemoteStreamAdded(MediaStream stream, NBMPeerConnection connection) {
        // 获取到远端视频流 -- 添加 远端视频流 到视图上
        stream.videoTracks.get(0).addRenderer(new VideoRenderer(remoteRender));
    }

    public void onRemoteStreamRemoved(MediaStream stream, NBMPeerConnection connection) {
        // 移除 远端视频流
        stream.videoTracks.get(0).removeRenderer(new VideoRenderer(remoteRender));
    }

    public void onPeerConnectionError(String error) {
        Log.d(TAG, "onPeerConnectionError");
    }
    public void onDataChannel(DataChannel dataChannel, NBMPeerConnection connection) {

    }

    @Override
    public void onBufferedAmountChange(long l, NBMPeerConnection connection, DataChannel channel) {

    }

    @Override
    public void onStateChange(NBMPeerConnection connection, DataChannel channel) {

    }

    @Override
    public void onMessage(DataChannel.Buffer buffer, NBMPeerConnection connection, DataChannel channel) {

    }

    public void onBufferedAmountChange(long l, NBMPeerConnection connection) {

    }
    public void onStateChange(NBMPeerConnection connection) {

    }
    public void onMessage(DataChannel.Buffer buffer, NBMPeerConnection connection) {

    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getFromUserId() {
        return fromUserId;
    }

    public void setFromUserId(String fromUserId) {
        this.fromUserId = fromUserId;
    }

    public String getConnectionId() {
        return connectionId;
    }

    public void setConnectionId(String connectionId) {
        this.connectionId = connectionId;
    }

}